<?php

defined('BASEPATH') or die('forbidden');

/**
 * 钩子类
 * @author  Karson
 * @name    hooks.php
 * @since   2013-5-14 10:34:21
 */
class Hooks {

    var $enabled = false;
    var $hooks = array();
    var $in_progress = false;

    function __construct() {
        $this->initialize();
    }

    function initialize() {
        if (is_file(APPPATH . 'configs/hooks.php')) {
            include(APPPATH . 'configs/hooks.php');
        }
        if (!isset($config['hooks']) || !is_array($config['hooks'])) {
            return;
        }
        $this->hooks = & $config['hooks'];
        $this->enabled = true;
    }

    /**
     * 调用钩子
     * @param string $which 钩子标识
     * @param array $params 钩子参数,必须为一个数组
     * @return boolean
     */
    function call_hook($which = '', $params = array()) {
        if (!$this->enabled || !isset($this->hooks[$which])) {
            return false;
        }

        if (isset($this->hooks[$which][0]) && is_array($this->hooks[$which][0])) {
            foreach ($this->hooks[$which] as $val) {
                if (is_array($val) && isset($val['params']) && is_array($params)) {
                    $val['params'] = array_merge($val['params'], $params);
                    $this->run_hook($val);
                }
            }
        } else {
            $data = $this->hooks[$which];
            if (is_array($data) && isset($data['params']) && is_array($params)) {
                $data['params'] = array_merge($data['params'], $params);
                $this->run_hook($data);
            }
        }

        return true;
    }

    /**
     * 运行一个钩子
     */
    function run_hook($data) {
        if (!is_array($data)) {
            return false;
        }
        //钩子是否已经运行
        if ($this->in_progress == true) {
            return;
        }

        if (!isset($data['filepath']) || !isset($data['filename'])) {
            return false;
        }

        $filepath = APPPATH . $data['filepath'] . '/' . $data['filename'];
        if (!file_exists($filepath)) {
            return false;
        }

        $class = isset($data['class']) && $data['class'] != '' ? $data['class'] : false;
        $function = isset($data['function']) ? $data['function'] : false;
        $params = isset($data['params']) ? $data['params'] : '';

        if ($class === false && $function === false) {
            return false;
        }

        //设置钩子状态为运行
        $this->in_progress = true;

        if ($class !== false) {
            //如果类名不为空则创建对象并调用
            if (!class_exists($class, false)) {
                require($filepath);
            }
            $hook = new $class;
            $hook->$function($params);
        } else {
            //如果类名为空则调用函数
            if (!function_exists($function)) {
                require($filepath);
            }
            $function($params);
        }

        $this->in_progress = false;
        return true;
    }

}